﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;

namespace Mga
{
	public class XLuaComponent : MonoBehaviour
	{
		static LuaEnv luaEnv = null;

		internal static float lastGCTime = 0;
		internal const float GCInterval = 1;//1 second 
		private Action luaStart;
		private Action luaUpdate;
		private Action luaOnDestroy;
		private LuaTable scriptEnv;
		//public Injection[] injections;
		public static LuaEnv LuaEnv
		{
			get
			{
				return luaEnv;
			}
		}

		void Awake()
		{
			luaEnv = new LuaEnv();

			luaEnv.AddLoader((ref string filename) =>
			{
				//TODO:修改AB中的路径
				//if (GameEntry.Base.EditorResourceMode)
				return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(Application.dataPath + "/Lua/" + filename.Replace('.', '/') + ".lua"));
				//else
				//    return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(string.Format("Assets/Lua/{0}.lua.bytes", filename.Replace('.', '/'))));
			});

			scriptEnv = luaEnv.NewTable();

			LuaTable meta = luaEnv.NewTable();
			meta.Set("__index", luaEnv.Global);
			scriptEnv.SetMetaTable(meta);
			meta.Dispose();

			scriptEnv.Set("self", this);
			//foreach (var injection in injections)
			//{
			//    scriptEnv.Set(injection.name, injection.value);
			//}

			luaEnv.DoString("require 'main'", "XLuaComponent", scriptEnv);

			Action luaAwake = scriptEnv.Get<Action>("awake");
			scriptEnv.Get("start", out luaStart);
			scriptEnv.Get("update", out luaUpdate);
			scriptEnv.Get("ondestroy", out luaOnDestroy);

			if (luaAwake != null)
			{
				luaAwake();
			}
		}

		void Start()
		{
			if (luaStart != null)
			{
				luaStart();
			}
		}

		void Update()
		{
			if (luaUpdate != null)
			{
				luaUpdate();
			}
			luaEnv.Tick();
			//if (Time.time - XLuaComponent.lastGCTime > GCInterval)
			//{
			//	luaEnv.Tick();
			//	XLuaComponent.lastGCTime = Time.time;
			//}
		}

		void OnDestroy()
		{
			if (luaOnDestroy != null)
			{
				luaOnDestroy();
			}
			luaOnDestroy = null;
			luaUpdate = null;
			luaStart = null;
			scriptEnv.Dispose();
			//injections = null;
		}

		/// <summary>
		/// 执行lua代码
		/// </summary>
		/// <param name="chunk">代码块 可以是require方式</param>
		/// <param name="chunkName">代码名</param>
		/// <param name="env">table</param>
		/// <returns></returns>
		public object[] DoString(string chunk, string chunkName = "chunk", LuaTable env = null)
		{
			return luaEnv.DoString(chunk, chunkName, env);
		}

		public object[] DoString(LuaEnv.CustomLoader loader, string chunk)
		{
			luaEnv.AddLoader(loader);
			return luaEnv.DoString(chunk);
		}

		public static byte[] ReadFile(string fileName)
		{
			if (Application.isEditor)
			{
				return File.ReadAllBytes(fileName);
			}
			return null;
		}
	}
}
